﻿// // #define Buged //C#的宏定义必须在所有代码之前。当前只让Buged宏有效
// //#define NoBug
// //#define Li
// // #define Zhang
// // using System;
// // using System.Diagnostics;//注意：ConditionalAttribute特性包含在此命名空间中


//C#标签，如果不依赖于C#本身的反射特性，那么它将不会产生任何作用。

//所以，一个完整的特性需要两个动作：

//创建特性
//通过反射为特性写一个解释程序

// https://blog.csdn.net/qq_42194657/article/details/102479826?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-102479826-blog-131208623.235^v38^pc_relevant_sort_base1&spm=1001.2101.3001.4242.1&utm_relevant_index=3

// namespace AttributeTest
// {
//     class Program
//     {
//         static void Main(string[] args)
//         {
//             ToolKit.FuncA();
//             ToolKit.FuncB();
//             ToolKit.FuncC();
//             ToolKit.FuncD();
//             // Console.ReadKey();
//         }
//     }

//     public class ToolKit
//     {
//         [ConditionalAttribute("Li")]//Attribute名称的长记法
//         [ConditionalAttribute("Buged")]
//         public static void FuncA()
//         {
//             Console.WriteLine("Created by Li, Buged");
//         }

//         [Conditional("Li")]//Attribute名称的短记法
//         [Conditional("NoBug")]
//         public static void FuncB()
//         {
//             Console.WriteLine("Created by Li, NoBug");
//         }

//         [Conditional("Zhang")]
//         [Conditional("Buged")]
//         public static void FuncC()
//         {
//             Console.WriteLine("Created by Zhang, Buged");
//         }

//         [Conditional("Zhang")]
//         [Conditional("NoBug")]
//         public static void FuncD()
//         {
//             Console.WriteLine("Created by Zhang, NoBug");
//         }
//     }
// }

// C# 特性（Attribute）总结
// https://blog.csdn.net/qq_44386034/article/details/131208623



// public static void ReflectionArrtibute<T>(T t) where T : Class
// {
//       Type type = t.GetType();//通过参数来获取Type类型
//       if (type.IsDefined(typeof(CustomAttribute),true)) //反射调用特性，记得一定要先判断，然后再获取
//       { 
//           foreach (CustomAttribute attribute in type.GetCustomAttributes()) //把所有标记的特性都实例化了
//           {
//               Console.WriteLine($"attribute.Id={attribute.Id}");
//               Console.WriteLine($"attribute.Name={attribute.Name}");
//               attribute.Do();
//           }
//           ///循环获取所有的属性上标记的特性，调用特性中的元素
//           foreach (PropertyInfo prop in type.GetProperties())
//           { 
//               if (prop.IsDefined(typeof(CustomAttribute), true))
//               {
//                   foreach (CustomAttribute attribute in prop.GetCustomAttributes()) //把所有标记的特性都实例化了
//                   {
//                       Console.WriteLine($"attribute.Id={attribute.Id}");
//                       Console.WriteLine($"attribute.Name={attribute.Name}");
//                       attribute.Do();
//                   }
//               }
//           }
//           ///循环获取所有的字段上标记的特性，调用特性中的元素
//           foreach (FieldInfo field in type.GetFields())
//           {
//               if (field.IsDefined(typeof(CustomAttribute), true))
//               {
//                   foreach (CustomAttribute attribute in field.GetCustomAttributes()) //把所有标记的特性都实例化了
//                   {
//                       Console.WriteLine($"attribute.Id={attribute.Id}");
//                       Console.WriteLine($"attribute.Name={attribute.Name}");
//                       attribute.Do();
//                   }
//               }
//            }
//           ///循环获取所有方法上标记的特性，调用特性中的元素
//           foreach (MethodInfo method in type.GetMethods())
//           {
//               if (method.IsDefined(typeof(CustomAttribute), true))
//               {
//                   foreach (CustomAttribute attribute in method.GetCustomAttributes()) //把所有标记的特性都实例化了
//                   {
//                       Console.WriteLine($"attribute.Id={attribute.Id}");
//                       Console.WriteLine($"attribute.Name={attribute.Name}");
//                       attribute.Do();
//                   }
//               }
//           } 
// }

//using System;
//using System.Collections.Generic;
//using System.Reflection;

//public abstract class AbstractValidateAttribute : Attribute
//{
//    public abstract bool Validate(object oValue);
//}

////邮箱合法
//[AttributeUsage(AttributeTargets.Property)]
//public class EmailValidateAttribute : AbstractValidateAttribute
//{
//    public override bool Validate(object value)
//    {
//        if (value != null)
//        {
//            return true;//实际的判断
//        }
//        else
//        {
//            return false;
//        }
//    }
//}
////公司ID在1000~10000范围
//[AttributeUsage(AttributeTargets.Property)]
//public class IntValidateAttribute : AbstractValidateAttribute
//{
//    private int _Min = 0;
//    private int _Max = 0;

//    public IntValidateAttribute(int min, int max)
//    {
//        this._Min = min;
//        this._Max = max;
//    }

//    public override bool Validate(object oValue)
//    {
//        return oValue != null && int.TryParse(oValue.ToString(), out int num) && num >= this._Min && num <= this._Max;
//    }
//}


//public class BaseDAL
//{
//    public static void Save<T>(T t)
//    {
//        Type type = t.GetType();
//        bool isSafe = true;
//        {
//            // 遍历类中的所有属性
//            foreach (var property in type.GetProperties())
//            {
//                if (property.IsDefined(typeof(AbstractValidateAttribute), true)){
//                    //特性类的实例化就在反射发生的时候
//                    IEnumerable<Attribute> oAttributeArray = property.GetCustomAttributes(typeof(AbstractValidateAttribute), true);
//                    // 遍历类中的所有属性中的 特性
//                    foreach (var oAttribute in oAttributeArray)
//                    {
//                        //转为基类对象
//                        AbstractValidateAttribute validateAttribute = oAttribute as AbstractValidateAttribute;
//                        isSafe = validateAttribute.Validate(property.GetValue(t));
//                        if (isSafe)
//                        {
//                            Console.WriteLine($"{oAttribute.ToString()}保存到数据库");
//                        }
//                        else
//                        {
//                            Console.WriteLine($"{oAttribute.ToString()}数据不合法");
//                            property.SetValue(t, null);// 强制把属性修改成null                           
//                        }
//                    }
//                }


//            }
//        }

//    }
//}

//public class UseModel
//{
//    //邮箱
//    [EmailValidate]
//    public string Email { get; set; }
//    //企业ID
//    [IntValidate(1000, 10000)]
//    public int CompanyID { get; set; }

//    public UseModel(string email, int id)
//    {
//        this.Email = email;
//        this.CompanyID = id;
//    }
//}

//class MyAttribute
//{
//    static void Main(string[] args)
//    {
//        Console.OutputEncoding = System.Text.Encoding.Unicode;

//        UseModel useModel = new UseModel("小米", 120000);
//        BaseDAL.Save<UseModel>(useModel);

//        Console.ReadKey();

//    }
//}

//特性实现枚举展示描述信息

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.Field)]
public class RemarkAttribute : Attribute
{
    public string Remark { get; set; }
    public RemarkAttribute(string remark)
    {
        this.Remark = remark;
    }
}

public enum UserState
{
    //正常状态
    [Remark("正常状态")]
    Normal = 0,
    //冻结状态
    [Remark("冻结状态")]
    Frozen = 1,
    //删除状态
    [Remark("删除状态")]
    Deleted = 2

}
//通过反射调用特性

    // 拓展方法
public static class AttributeExtend
{
    public static string GetRemark(this Enum value)
    {
        Type type = value.GetType();// 取得类型 UserState
        var field = type.GetField(value.ToString());// 取得字段
        if (field.IsDefined(typeof(RemarkAttribute), true))// 判断字段是否有自定义特性：RemarkAttribute
        {   // 取得字段上自定义特性RemarkAttribute ，并且实例化后得到attribute
            RemarkAttribute attribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute), true);
            // 调用实例化对象attribute的属性Remark，并且返回执行结果
            return attribute.Remark;
        }
        else
        {
            return value.ToString();
        }
    }
}

class Csharp17
{

    static void Main(string[] args)
    {
        UserState userState = UserState.Frozen;
        string reamrk = userState.GetRemark();
        // 打印 自定义特性.Remark的值
        Console.WriteLine(reamrk);
    }
}
